<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>SQL转Java JPA、MYBATIS实现类代码生成平台</title>
    <meta name="keywords" content="sql转实体类,sql转DAO,SQL转service,SQL转JPA实现,SQL转MYBATIS实现">
    <#import "common/common-import.ftl" as netCommon>
    <@netCommon.commonStyle />

    <@netCommon.commonScript />
</head>
<body style="background-color: #e9ecef">
<!-- Main jumbotron for a primary marketing message or call to action -->
<div class="jumbotron">
    <div class="container">
        <h2>Code Generator</h2>
    <#--        <p class="lead">-->
    <#--            基于<code>SpringBoot2</code>+<code>Freemarker</code>的代码生成器，用<code>DDL SQL</code>语句生成<code>JPA</code>/<code>JdbcTemplate</code>/<code>Mybatis</code>/<code>MybatisPlus</code>/<code>BeetlSQL</code>相关代码，支持<code>mysql</code>/<code>oracle</code>/<code>pgsql</code>三大数据库。以<code>释放双手</code>为目的，各大模板也在陆续补充和优化。欢迎大家多多提交模板和交流想法，如果发现有SQL语句不能识别，请<a href="https://github.com/moshowgame/SpringBootCodeGenerator/issues">留言</a>给我分析，同时欢迎大家进行<a href="https://github.com/moshowgame/SpringBootCodeGenerator/pulls">PullRequest</a>和<a href="#" id="donate1">赞赏</a>，谢谢！-->
    <#--        </p>-->
        <div class="input-group mb-3">
            <div class="input-group-prepend">
                <span class="input-group-text">微服务模块名称</span>
            </div>
            <input type="text" class="form-control" id="moduleName" name="moduleName" placeholder="">
            <div class="input-group-prepend">
                <span class="input-group-text">作者名称</span>
            </div>
            <input type="text" class="form-control" id="authorName" name="authorName" placeholder="harry">

        <div class="input-group-prepend">
        <span class="input-group-text">包名路径</span>
                  </div>
             <input type="text" class="form-control" id="packageName" name="packageName" placeholder="com.dbapp.dsc">
        </div>
        <div class="input-group mb-3">

            <div class="checkbox" >
                <label >
                    <input type="checkbox"  name="useLombok" id="useLombok" checked="true">使用lombok
                </label>
                <label style="padding-left: 10px">
                    <input type="checkbox"  name="useProtobuf" id="useProtobuf" checked="false">使用Protobuf
                </label>
                <label style="padding-left: 10px">
                    <input type="checkbox"  name="useMapstruct" id="useMapstruct" checked="true">使用mapstruct
                </label>
                <label style="padding-left: 10px">
                    <input type="checkbox"  name="longToString" id="longToString" checked="true">longToString
                </label>
            </div>
        </div>
        <textarea id="ddlSqlArea" placeholder="请输入表结构信息..." class="form-control btn-lg" style="height: 250px;">
CREATE TABLE `user_info` (
  `id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '用户ID',
  `user_name` varchar(255) NOT NULL COMMENT '用户名',
  `email` VARCHAR(191) NOT NULL COMMENT '电子邮件',
  `lang_key` VARCHAR(10) NOT NULL COMMENT '语言：{"zh-CN","en-US"}',
  `created_date` TIMESTAMP NOT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户信息'
        </textarea><br>
        <p>
            <button class="btn btn-primary btn-lg disabled" id="btnGenCode" role="button" onclick="onGenerateCodeBtnClick()">开始生成 »</button>

        </p>
        <p style="display:none;" id="btnDownloadDiv">
            <a   id="btnDownload" >下载 »</a>
        </p>
        <div id="operationBtnList"></div>

        <textarea id="genCodeArea" class="form-control btn-lg"></textarea>
    </div>
</div>



<script id="operationBtnTemplate" type="text/x-jsrender">
<div class="container">
   {{props data }}
    {{if "filePath"!=key}}
      <div class="row" style="margin-top: 10px;">

            <div class="btn-toolbar col-md-12" role="toolbar" aria-label="Toolbar with button groups">
                <div class="input-group">
                    <div class="input-group-prepend">
                        <div class="btn btn-secondary disabled" id="btnGroupAddon">{{:key}}</div>
                    </div>
                </div>

                <div class="btn-group" role="group" aria-label="First group">
                {{if 1=1 ~sectionKey=key}}
                    {{props prop }}
                        <button type="button" style="border-right: inset;" class="btn btn-default generator" id="{{:~sectionKey}}.{{:key}}" onClick="onViewCodeBtnClick(`{{:~sectionKey}}.{{:key}}`)"> {{:key}}</button>
                    {{/props}}
                {{/if}}

                </div>
            </div>
        </div>
         {{/if}}
        <hr/>
   {{/props}}
</div>
</script>

<script >
    document.getElementById("useProtobuf").checked = false;
    var codeData;
    // controller_ide
    var genCodeArea = CodeMirror.fromTextArea(document.getElementById("genCodeArea"), {
        lineNumbers: true,
        matchBrackets: true,
        mode: "text/x-java",
        lineWrapping: true,
        readOnly: true,
        foldGutter: true,
        gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"]
    });

    genCodeArea.setSize('auto', 'auto');
    var ddlSqlArea = CodeMirror.fromTextArea(document.getElementById("ddlSqlArea"), {
        lineNumbers: true,
        matchBrackets: true,
        mode: "text/x-sql",
        lineWrapping: false,
        readOnly: false,
        foldGutter: true,
        gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"]
    });
    ddlSqlArea.setSize('auto', 'auto');

    function copyText(text, callback) { // text: 要复制的内容， callback: 回调
        var tag = document.createElement('textarea');
        tag.setAttribute('id', 'cp_hgz_input');
        tag.value = text;
        document.getElementsByTagName('body')[0].appendChild(tag);
        document.getElementById('cp_hgz_input').select();
        document.execCommand('copy');
        document.getElementById('cp_hgz_input').remove();

        layer.open({
            icon: '1',
            content: ('复制成功，可粘贴')
        });
        if (callback) {
            callback(text)
        }
    }
    function findNodeByJsonPath(object, path) {
        var props = path.split(".");
        for(var i=0;i<props.length;i++){
            var p = props[i];
            if(object && object.hasOwnProperty(p)){
                object = object[p];
            }
            else{
                return undefined;
            }
        }
        return object;
    }
    function getCodeMirrorNative(target) {
        var _target = target;
        if (typeof _target === 'string') {
            _target = document.querySelector(_target);
        }
        if (_target === null || !_target.tagName === undefined) {
            throw new Error('Element does not reference a CodeMirror instance.');
        }

        if (_target.className.indexOf('CodeMirror') > -1) {
            return _target.CodeMirror;
        }

        if (_target.tagName === 'TEXTAREA') {
            return _target.nextSibling.CodeMirror;
        }

        return null;
    };
    function onViewCodeBtnClick(path){
        if (!$.isEmptyObject(codeData)) {
            var code = findNodeByJsonPath(codeData,path)
            if (code) {
                genCodeArea.setValue(code);
                copyText(getCodeMirrorNative("#genCodeArea").getDoc().getValue())

            }
            genCodeArea.setSize('auto', 'auto');
        }
    }

    /**
     * 生成代码
     */
    function onGenerateCodeBtnClick(){
        var tableSql = ddlSqlArea.getValue();
        var data = {
            "tableSql": tableSql ,
            "packageName": encodeURIComponent($("#packageName").val()),
            "moduleName": encodeURIComponent($("#moduleName").val()),
            "authorName": encodeURIComponent($("#authorName").val()),
            "useLombok": document.getElementById("useLombok").checked,
            "useProtobuf": document.getElementById("useProtobuf").checked,
            "useMapstruct": document.getElementById("useMapstruct").checked,
            "longToString": document.getElementById("longToString").checked
        }
        console.log(data)
        $.ajax({
            type: 'POST',
            url: base_url + "/generateCode",
            data: data,
            dataType: "json",
            success: function (data) {
                if (data.code == 200) {
                    var filePath = data.data.filePath;
                    console.log(filePath)
                    if (data.data && data.data.filePath) {
                        $("#btnDownloadDiv").css('display','block');
                        var downloadUrl = 'download?fileName='+data.data.filePath;
                        $('#btnDownload').attr('href',downloadUrl);
                        // use HTML5 a[download] attribute to specify filename
                        // var a = document.createElement("a");
                        // // safari doesn't support this yet
                        // if (typeof a.download === 'undefined') {
                        //     window.location = downloadUrl;
                        // } else {
                        //     a.href = downloadUrl;
                        //     // a.download = filename;
                        //     document.body.appendChild(a);
                        //     a.click();
                        // }
                        //
                        // setTimeout(function () { URL.revokeObjectURL(downloadUrl); }, 100); // cleanup
                    }
                    layer.open({
                        icon: '1',
                        content: "代码生成成功",

                    });
                    var template = $.templates("#operationBtnTemplate");

                    var htmlOutput = template.render(data);
                    $("#operationBtnList").html(htmlOutput);

                    codeData = data.data;
                    if (codeData.backend && codeData.backend.domain ) {
                        genCodeArea.setValue(codeData.backend.domain);
                    }
                    genCodeArea.setSize('auto', 'auto');

                } else {
                    layer.open({
                        icon: '2',
                        content: (data.msg || '代码生成失败')
                    });
                }
            }
        });
    }
    /**
     * 生成代码
     */
    function onDownloadCodeBtnClick(){
        console.log("==========onDownloadCodeBtnClick=======")

        var tableSql = ddlSqlArea.getValue();


        $.ajax({
            type: 'POST',
            url: base_url + "/download",
            data: {
                "tableSql": tableSql,
                "packageName": $("#packageName").val(),
                "moduleName": $("#moduleName").val(),
                "authorName": $("#authorName").val()
            },
            // dataType: "json",
            // contentType: 'application/json',
            success: function(response, status, xhr) {
                console.log("==========status======="+status,response.zip)
                // check for a filename
                var filename = "";
                var disposition = xhr.getResponseHeader('Content-Disposition');
                if (disposition && disposition.indexOf('attachment') !== -1) {
                    var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
                    var matches = filenameRegex.exec(disposition);
                    if (matches != null && matches[1]) filename = matches[1].replace(/['"]/g, '');
                }

                var type = xhr.getResponseHeader('Content-Type');
                var blob = new Blob([response], { type: type });

                if (typeof window.navigator.msSaveBlob !== 'undefined') {
                    // IE workaround for "HTML7007: One or more blob URLs were revoked by closing the blob for which they were created. These URLs will no longer resolve as the data backing the URL has been freed."
                    window.navigator.msSaveBlob(blob, filename);
                } else {
                    var URL = window.URL || window.webkitURL;
                    var downloadUrl = URL.createObjectURL(blob);

                    if (filename) {
                        // use HTML5 a[download] attribute to specify filename
                        var a = document.createElement("a");
                        // safari doesn't support this yet
                        if (typeof a.download === 'undefined') {
                            window.location = downloadUrl;
                        } else {
                            a.href = downloadUrl;
                            a.download = filename;
                            document.body.appendChild(a);
                            a.click();
                        }
                    } else {
                        window.location = downloadUrl;
                    }

                    setTimeout(function () { URL.revokeObjectURL(downloadUrl); }, 100); // cleanup
                }
            },
            error:function (error) {
                console.log("============download error==========")
                console.log(error)

            }
        });

    }


</script>

</body>
</html>
